#pragma once
#include <sys/epoll.h>
#include "Connection.hpp"
#include "common.hpp"
#include "Addr.hpp"
class Reactor;
// 专门用于普通fd的管理
class Channel : public Connection
{
public:
    Channel(int fd, Addr &client)
        : _client(client)
    {
        SetEvents(EPOLLIN | EPOLLET);
        SetFd(fd);
        SetNonBlock(fd);
    }
    void RegisterHandler()
    {

    }
    void Recver()
    {
        std::cout<<"进入channel的Recver模块"<<std::endl;
        char buffer[1024];
        while (true)
        {
            buffer[0] = 0;
            int fd = GetFd();
            ssize_t n = recv(fd, buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                // 成功读取
                buffer[n] = 0;
                _inbuffer += buffer;
            }
            else if (n == 0)
            {
                Excepter();
                return;
            }
            else
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    // 出错
                    Excepter();
                    return;
                }
            }
        }
        std::cout<<"退出channel的Recver模块"<<std::endl;
        //此时就可以进行对_inbuffer进行处理
        if(!_inbuffer.empty())
        {
            _outbuffer+=_handler(_inbuffer);
        }
        std::cout<<"_outbuffer:\n"<<_outbuffer<<std::endl;
        if(!_outbuffer.empty())
        {
            Sender();
        }
    }
    void Sender()
    {
        std::cout<<"进入channel的Sender模块"<<std::endl;
        int fd=GetFd();
        while(true)
        {
            int n=send(fd,_outbuffer.c_str(),_outbuffer.size(),0);
            if(n>0)
            {
                //写入的数据就需要从_inbuffer里边删去
                _outbuffer.erase(0,n);
                if(_outbuffer.empty())
                {
                    //删去之后_outbuffer空了,说明写的数据已经写完了
                    break;
                }
            }
            else if(n==0)
            {
                break;
            }
            else
            {
                //此时n<0,要判断错误码
                if(errno==EWOULDBLOCK||errno==EAGAIN)
                {
                    //此时说明是此时没有数据,需要稍后再试
                    break;
                }
                else if(errno==EINTR)
                {
                    //被信号打断,可以继续读
                    continue;
                }
                else
                {
                    //进行出错处理
                    Excepter();
                    return;
                }
            }
        }
        //出了while循环:1,_outbuffer为空,数据已经写完了
        //              2,此时还没有数据,需要稍后再试
        if(!_outbuffer.empty())
        {
            //此时_outbuffer不为空,我们需要手动开启一次对写事件的关心
            GetOwner()->EnableWriteRead(GetFd(),true,true);
        }
        else
        {
            //此时_outbuffer已经为空,我们就需要关闭写事件的关心
            GetOwner()->EnableWriteRead(GetFd(),true,false);
        }
    }
    void Excepter()
    {
        GetOwner()->DelConnection(GetFd());
    }
    ~Channel()
    {
    }

private:
    std::string _inbuffer;  // 输入buffer
    std::string _outbuffer; // 输出buffer
    Addr _client;           // 客户信息
};